package com.molichuxing.services.business.service.impl;

import com.molichuxing.framework.exception.BizException;
import com.molichuxing.services.business.convertor.Convert;
import com.molichuxing.services.business.dto.request.create.LawsuitCreateBizDto;
import com.molichuxing.services.business.dto.response.OverdueBizDto;
import com.molichuxing.services.business.service.LawsuitBizService;
import com.molichuxing.services.business.service.OrderScheduleBizService;
import com.molichuxing.services.exception.OrderExceptionCodeEnum;
import com.molichuxing.services.infrastructure.dto.response.OrderExclusivelDto;
import com.molichuxing.services.infrastructure.dto.response.OrderReturnDto;
import com.molichuxing.services.infrastructure.service.*;
import com.molichuxing.services.property.OrderExclusivelStatusEnum;
import com.molichuxing.services.property.OrderScheduleStatusEnum;
import com.molichuxing.services.property.RecycleStateEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDate;

/**
 * @Author zoumingyu
 * @Date 2020年07月30日
 */
@Service("lawsuitBizService")
public class LawsuitBizServiceImpl implements LawsuitBizService {
    private static final Logger logger = LoggerFactory.getLogger(LawsuitBizServiceImpl.class);

    @Resource
    private LawsuitService lawsuitService;

    @Resource
    private OrderExclusivelService orderExclusivelService;

    @Resource
    private OrderStatusFlowService orderStatusFlowService;

    @Resource
    private OrderReturnService orderReturnService;

    @Resource
    private OrderScheduleService orderScheduleService;

    @Resource
    private OrderRenegeService orderRenegeService;

    @Resource
    private OrderScheduleBizService orderScheduleBizService;

    /**
     * 新增法务诉讼
     *
     * @param createBizDto 新增参数
     * @return boolean
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
    public boolean create(LawsuitCreateBizDto createBizDto) {
        // 根据订单号查询订单信息
        OrderExclusivelDto orderExclusivel = orderExclusivelService.getOrderExclusivel(createBizDto.getOrderCode());
        if (orderExclusivel == null) {
            logger.error("[create]订单({})不存在", createBizDto.getOrderCode());
            throw new BizException(OrderExceptionCodeEnum.NOT_EXIST.getCode(), "新增操作失败, 订单信息不存在");
        } else if (OrderExclusivelStatusEnum.LAWSUIT.equals(orderExclusivel.getOrderStatus())) {
            logger.error("[create]订单({})已经诉讼", createBizDto.getOrderCode());
            throw new BizException(OrderExceptionCodeEnum.STATUS_ERROR.getCode(), "新增操作失败, 订单已诉讼");
        }
        // 查询逾期信息
        OverdueBizDto overdue = orderScheduleBizService.getOverdue(createBizDto.getOrderCode(), LocalDate.now());
        // 保存诉讼信息
        if (!lawsuitService.create(Convert.toLawsuitCreateDto(createBizDto, orderExclusivel, overdue))) {
            return false;
        }

        // 判断是否已退租
        if (OrderExclusivelStatusEnum.RENEGE_ACCEPTED.getValue() <= orderExclusivel.getOrderStatus().getValue()) {
            // 退租，修改退租状态
            orderRenegeService.modifyLawsuit(createBizDto.getOrderCode());
        }

        // 修改订单状态
        if (!orderExclusivelService.modify(createBizDto.getOrderCode(), orderExclusivel.getOrderStatus(),
                OrderExclusivelStatusEnum.LAWSUIT)) {
            logger.error("[create]修改订单({})状态失败", createBizDto.getOrderCode());
            throw new BizException(OrderExceptionCodeEnum.ERROR.getCode(), "新增操作失败");
        }
        // 新增流转
        if (!orderStatusFlowService.createOrderStatusFlow(Convert.toOrderStatusFlowCreateDto(createBizDto))) {
            logger.error("[create]新增订单({})流转失败", createBizDto.getOrderCode());
            throw new BizException(OrderExceptionCodeEnum.ERROR.getCode(), "新增操作失败");
        }

        // 修改排期计划-终止
        orderScheduleService.modifyCancel(createBizDto.getOrderCode(), OrderScheduleStatusEnum.NO);

        return true;
    }

    /**
     * 完成诉讼
     *
     * @param orderCode 订单号
     * @return boolean
     */
    @Override
    public boolean modifyLawsuitComplete(Long orderCode) {
        // 查询是否已还车/进行收车操作
        OrderReturnDto orderReturn = orderReturnService.getOrderReturn(orderCode);
        if (orderReturn == null) {
            logger.error("[modifyLawsuitComplete]订单({})完成诉讼失败，未收车", orderCode);
            throw new BizException(OrderExceptionCodeEnum.ERROR.getCode(), "完成诉讼操作失败");
        } else if (RecycleStateEnum.FAIL.getValue() == orderReturn.getRecycleState()) {
            logger.error("[modifyLawsuitComplete]订单({})完成诉讼失败，收车失败", orderCode);
            throw new BizException(OrderExceptionCodeEnum.ERROR.getCode(), "完成诉讼操作失败");
        }
        // 完成诉讼
        return lawsuitService.modifyComplete(orderCode);
    }
}
